/**
 * @description
 * @author ybjuejue
 * @createDate 2018/12/25/025
 */
;(function (global) {
    /**模块内部全局变量**/
    var key = 'YRKjRlUXkCZG2KtpKbcvGj4AX0ANdEt1';

    var _ = global || window;
    if (!global) {
        console.error('need cmp.js');
        return;
    }
    var cityCenterLanLats = {}, // 缓存已加载过城市中心点位置
        poiCacheInfos = {};// 缓存已加载过度地图点的详细信息
    var checkType = { // 类型检查
        function: function (fn) {
            return typeof fn === 'function' ? fn : function () {};
        },
        array: function (arr) {
            return Object.prototype.toString.call(arr) === '[object Array]' ? arr : []
        },
        object: function (obj) {
            return Object.prototype.toString.call(obj) === '[object Object]' ? obj : {}
        }
    };
    var request = new Request();
    // lbs
    var converLnglat = converFrom();
    var map = null;
    var ready = null;
    console.log(_.h5lbs)
    if (typeof _.h5lbs !== 'object') {
        _.h5lbs = {}
    }
    // 获取转换文件路径
    function convertFilePath4Token(filePath){
        filePath = filePath.indexOf('?')>-1 ? filePath + '&' :  filePath+ '?';
        filePath = filePath + 'token='+_.token;
        return filePath;
    }
    // 构建定位返回数据
    function buildPositionResult(e) {
        var result = {
            lbsAddr:e.address,
            lbsCity:e.cityname,
            lbsCountry:e.country||"中国",
            lbsProvince:e.pname,
            lbsStreet:e.street,
            lbsTown:e.adname,
            lbsLatitude:e.position.lat,
            lbsLongitude:e.position.lng,
            lbsContinent:null,
            lbsComment:null,
            createDate:null,
            category:2
        };
        if (e.id && e.id.indexOf('user_') < 0) {
            result.lbsPoiId = e.id
        }
        return result;
    }
    // 初始化h5地图实例
    function initMap(callback) {
        if (!map &&!ready) {
            var container = document.createElement('div');
            container.style.cssText = 'display:none;with:0;height:0;overflow:hidden;';
            map = lbsMapBase(container, {
                success: function () {
                    ready = true;
                    callback(map)
                }
            });
        } else if (!ready) {
            map.ready(function () {
                ready = true;
                callback(map)
            });
        } else {
            callback(map);
        }
    }
    /**定位操作**/
    function getCurrentPosition (success, error) {
        initMap(function (map) {
            map.getCurrentPosition(success, error);
        })
    }
    // h5定位操作
    function getH5LocationInfo(option) {
        var opt =  {
            mode: option.mode === 2 ? 2 : 1,
            success: option.success || function () {},
            error: option.error || function () {}
        };
        var recode = [];
        if (opt.mode === 2) {
            getCurrentMultiPosition();
        } else {
            getCurrentPosition(function (res) {
                opt.success(res);
            }, function () {
                opt.error({msg:"定位失败"});
            })
        }
        function getCurrentMultiPosition() {
            getCurrentPosition(function (res) {
                opt.success(res);
                getCurrentMultiPosition();
            }, function () {
                opt.error({msg:"定位失败"});
            })
        }
    }
    // h5-M3 位置定位，获取当前的经纬度，以及时间、地名信息
    function getM3LocationInfo(option) {
        cordova.exec(
            option.success,
            option.error,
            "AMapLocationPlugin",
            "getLocationInfo",
            [
                {
                    mode:option.mode + ""
                }
            ]
        );
    }
    // h5-M3 获取当前位置
    function getM3CurrentPosition(option) {
        cordova.exec(
            option.success,
            option.error,
            "AMapLocationPlugin",
            "getLocation",
            [
                {
                    mode:option.mode + ""
                }
            ]
        );
    }
    // h5 获取当前位置
    function getH5CurrentPosition(option) {
        getH5LocationInfo({
            mode: option.mode,
            success: function (data) {
                var result = {
                    success:true,//成功的标识
                    coordinate:{
                        longitude:data.position.lng, //经度
                        latitude:data.position.lat //维度
                    }
                };
                option.success && option.success(result);
            },
            error: function (e) {
                option.error && option.error(e);
            }
        });
    }

    /**获取服务器位置信息**/

    // h5 获取服务器位置信息
    function showH5LocationInfo (option) {
        // 返回不支持提示
        // "http://192.168.10.236:8085/mobile_portal/seeyon/rest/cmplbs/-8979061758779701706"
        if (!option.lbsUrl) {
            option.error && option.error({error: 'no server url'});
        } else {
            _.ajax({
                type: 'get',
                url: option.lbsUrl,
                dataType: 'JSON',
                headers: {
                    "Accept": "application/json; charset=utf-8",
                    "Accept-Language": "zh-CN",
                    "Content-Type": "application/json; charset=utf-8",
                    "token": _.token
                },
                success: function (data) {
                    _.h5lbs.showLocationUi(data, option);
                },
                error: function (data) {
                    option.error && option.error(data);
                }
            });
        }
    }
    // h5-M3 获取服务器位置信息
    function showM3LocationInfo (_options) {
        if(_.platform.M3W){
            _options.lbsUrl = convertFilePath4Token(_options.lbsUrl);
        }
        cordova.exec(
            _options.success,
            _options.error,
            "CMPShowLocationPlugin",
            "showLocation",
            [
                {
                    "lbsUrl":_options.lbsUrl,
                    "userName":_options.userName,
                    "memberIconUrl":_options.memberIconUrl
                }
            ]
        );
    }
    /**地图标记**/
    // h5-M3地图标记 使用原生界面 本版本不用
    function markM3Location (opt) {
        cordova.exec(
            opt.success,
            opt.error,
            "CMPLocationMarkPlugin",
            "markLocation",
            [
                {
                    showMap:opt.showMap?"1":"0",
                    extData:opt.extData
                }
            ]
        );
    }
    // h5地图标记 使用h5界面
    function markH5Location (option) {
        if (lbsMapUi) {
            lbsMapUi({
                success: function (data) {
                    option.success&&option.success(buildPositionResult(data));
                },
                cancel: option.cancel,
                error: option.error
            }, {i18n: 'cmp.lbsMapUi.defaultTitle'})
        } else {
            console.error('need cmp.lbsMapUi.js');
            option.error && option.error();
        }
    }
    /**拍照定位**/
    // h5-M3 拍照定位
    function takeM3Picture (option) {
        if(_.platform.M3W){
            option.uploadPicUrl = convertFilePath4Token(option.uploadPicUrl)
        }
        cordova.exec(
            option.success,
            function(error){
                if(error.code == 27003){
                    if(typeof option.cancel == "function"){
                        option.cancel(error);
                    }
                }else {
                    if(typeof _options.error == "function"){
                        option.error(error);
                    }
                }
            },
            "CMPTakePicturePlugin",
            "takePicture",
            [
                {
                    "userName": option.userName,
                    "uploadPicUrl":option.uploadPicUrl,
                    "serverDateUrl":option.serverDateUrl,
                    "location":option.location
                }
            ]
        );
    }


    /***接口开放***/
    _.h5lbs.getCurrentPosition = function (option) {
        var opts = {
            success: null,
            error: null,
            mode:1//1：单次定位，2：多次定位
        };
        opts = _.extend(opts, option);
        if(_.platform.CMPShell){  //如果是cmp平台
            getM3CurrentPosition(opts);
        }else if(_.platform.wechatOrDD){ //如果是微信或者钉钉平台
            getH5CurrentPosition(opts)
        }else if(_.platform.third){
            _.event.trigger("cmpThirdPlatformPlugins",document,{data:opts,backupsFun:getH5CurrentPosition,plugin:"getPosition"})
        }
    };
    _.h5lbs.getLocationInfo = function (option) {
        var opts = {
            success: null,
            error: null,
            mode:1//1：单次定位，2：多次定位
        };
        opts = _.extend(opts, option);
        if(_.platform.CMPShell) {  //如果是cmp平台
            getM3LocationInfo(opts);
        } else {
            getH5LocationInfo({
                mode: opts.mode,
                success: function (data) {
                    opts.success && opts.success(buildPositionResult(data));
                },
                error: function (e) {
                    opts.error && opts.error(e);
                }
            });
        }
    };
    _.h5lbs.showLocationInfo = function (option) {
        var _options = {
            success: null,
            error: null,
            "lbsUrl":"", //  获取lbs信息的url地址 http://10.5.6.240:88/seeyon/rest/cmplbs/1814357976477972035
            "userName":"", // 用户名（可以不传）
            "memberIconUrl":"" // 用户头像url地址 （可以不传）
        };
        _options = _.extend(_options, option);
        _options.lbsUrl = 'http://192.168.10.236:8085/mobile_portal/seeyon/rest/cmplbs/-8979061758779701706';
        if(!_.platform.CMPShell) {  //如果是cmp平台
            // showM3LocationInfo(_options);
            showH5LocationInfo(_options);
        }
        else {
            showH5LocationInfo(_options);
        }
    };
    _.h5lbs.markLocation = function (option) {
        var opt = {
            success: null,
            error: null,
            cancel: null
        };
        opt = _.extend(opt, option);
        if(_.platform.CMPShell) {  //如果是cmp平台
            markH5Location(opt)
        }
        else {
            markH5Location(opt)
            // 返回不支持提示
        }
    };
    _.h5lbs.takePicture = function (option) {
        var opt = {
            success: null,
            error: null,
            cancel:null,
            "userName":"",
            "uploadPicUrl":"http://10.5.6.240:88/file/upload/",
            "serverDateUrl":"",
            "location":""
        };
        opt = _.extend(opt, option);
        if(_.platform.CMPShell) {  //如果是cmp平台
            takeM3Picture(opt);
        }
        else {
            // 返回不支持提示
        }
    };
    _.h5lbs.gdMap = function (container, option) {
        var opt = {
            success: null,
            error: null,
            center:null,
            pathOps: []
        };
        opt = _.extend(opt, option);
        return lbsMapBase(container, opt);
    };



    // 创建接受请求实例
    function Request() {
        window.mapScriptLoader = checkType.object(window.mapScriptLoader);
        var that = this;
        that.jsonp = function (xyUrl, callback, error) {
            var callbackName = 'cmpmap_' + Math.round(Math.random() * 100000);    //随机函数名
            mapScriptLoader[callbackName] = function(xyResult){
                delete mapScriptLoader[callbackName];    //调用完需要删除改函数
                checkType.function(callback)(xyResult);
            };
            that.script(xyUrl+'&callback=mapScriptLoader.'+callbackName, function () {}, function () {
                delete mapScriptLoader[callbackName];
                checkType.function(error)();
            }, true);
        };
        that.script = function (xyUrl, callback, error, status) {

            var head = document.getElementsByTagName('head')[0];
            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = xyUrl;
            script.onerror = checkType.function(error);
            script.onload = script.onreadystatechange = function(){
                if((!this.readyState || this.readyState === "loaded" || this.readyState === "complete")){
                    checkType.function(callback)();
                    script.onload = script.onreadystatechange = null;
                    if (status&& head && script.parentNode ) {
                        head.removeChild( script );
                    }
                }
            };
            head.insertBefore( script, head.firstChild );
        }
    }
    function callbackIntercept(success, error) {
        this.error = function (e) {
            checkType.function(error)(e);
        };
        this.success = function (e) {
            checkType.function(success)(e);
        }
    }
    // 构建简单对象合并
    function objectAssign(obj, obj2) {
        var one = checkType.object(obj);
        var two = checkType.object(obj2);
        if (typeof two === 'object') {
            for (var i in two) {
                if (two[i] || !(i in one)) {
                    one[i] = two[i];
                }
            }
        }
        return one;
    }
    // h5地图核心代码
    function lbsMapBase(dom, option) {
        var handle = new callbackIntercept(option.success, option.error);
        /**
         * @function name fixedMapOption
         * @description 修正构建地图配置项
         * @params opts 配置对象
         */
        function getLngLatType(lngLatType) {
            var lngLatTypesObj = {
                gps: '1',
                bd: '',
                other: '7',
                gd: '3'
            };
            lngLatType = lngLatTypesObj[lngLatType + ''] || null;
            return lngLatType
        }
        /**
         * @function name fixedMapOption
         * @description 修正构建地图配置项
         * @params opts 配置对象
         */
        function fixedMapOption(opts) {
            var opt = typeof opts === 'object' ? JSON.parse(JSON.stringify(opts)) : {};
            var options = {
                key: opts.key || key|| undefined,
                fixLngLat: opt.fixLngLat === true,
                lngLatType: getLngLatType(opt.lngLatType),
                noGeolocate: opts.noGeolocate === true,
                autoGeolocate: opts.autoGeolocate === true,
                autoSearch: opts.autoSearch === true,
                autoSearchCallback: checkType.function(opts.autoSearchCallback),
                toolBar: opts.toolBar === true,
                showPath: opts.showPath === true,
                pathOption: checkType.object(opts.pathOps),
                multiMarkers: opts.multiMarkers === true,
                markerOption: checkType.object(opts.markerOption),
                center: opts.center
            };
            options.plugin = {
                'Geolocation': !options.noGeolocate,
                'ToolBar': options.toolBar,
                'Autocomplete': options.search
            };
            return options
        }
        // 根据经纬度计算一个数据id；
        function getId(p) {return !p?undefined:'user_'+ p.lng + 't'+p.lat};
        // 初始化地图
        function buildMapInit(dom, options, lbs) {
            if ((!window.BMap)) {
                handle.error();
                return console.error("Don't have api Object!")
            }
            var api = BMap = BMap || window.BMap,
                cmpMap = new api.Map(dom, {enableMapClick: false}), convertor = new api.Convertor(),
                geolocation = new BMap.Geolocation(),
                // geocoder = new BMap.Geocoder(),
                ipGeolocation = new BMap.LocalCity();
            var isMarkClick = false;
            var $opts = fixedMapOption(options), isReady = false;
            lbs.lngLatPoint = lanLatPoint;
            lbs.getPixel = getPixel;
            lbs.distance = distance;
            lbs.$markers = {};
            lbs.$map = openMapActionFn();
            lbs.getAddressByLngLat = createGeocoder;
            lbs.convertLanLat = convertLanLat;
            lbs.getCurrentPosition = createGeolocation;
            lbs.getPoiDetail = getPoiDetail;
            createPlaceSearch();
            lbs.$center = {
                map: null,
                user: null,
                city: null
            };
            initMapEvent();
            createdMapCall(function () {
                if (!isReady) {
                    lbs.readyCallBack();
                    delete lbs.readyCallBack
                }
                isReady = true;
            });
            /**
             * @function getPoiDetail
             * @description 获取热点id 或经纬度查询
             * @params id 热点id
             * @params lnglat 选点经纬度
             */
            function getPoiDetail (id, lanlat, callback, status) {
                createGeocoder(lanlat, callback)
            }
            /**
             * @function initMapEvent
             * @description 初始化页面事件
             * @params cmpMap
             */
            function initMapEvent() {
                var dragendMoveend = false;
                cmpMap.addEventListener("moving", function (e) {
                    lbs.$map && lbs.$map.getCenter();
                });
                cmpMap.addEventListener("moveend", function (e) {
                    if (dragendMoveend) {
                        dragendMoveend = false;
                        lbs.$map && lbs.$map.getCenter();
                        lbs.$map && lbs.$map.getCity();
                    }
                });
                cmpMap.addEventListener("dragend", function (e) {
                    dragendMoveend = true;
                    lbs.$map && lbs.$map.getCenter();
                });
                dealMapClick();

                function dealMapClick() {
                    cmpMap.addEventListener("click", function (e) {
                        console.log('click');
                        console.log(e)
                        if (isMarkClick) {
                            isMarkClick = false
                            return
                        }
                        checkType.function(lbs.onclick).call(lbs, {
                            id: getId(e.point),
                            position: e.point
                        });
                    });
                    cmpMap.addEventListener("touchstart", function (e) {
                        cmpMap.disableDragging();
                    });
                    cmpMap.addEventListener("touchmove", function (e) {
                        cmpMap.enableDragging();
                    })
                    cmpMap.addEventListener("touchend", function (e) {
                        cmpMap.disableDragging();
                    });
                }
            };

            /**
             * @function name createGeolocation
             * @description 开发页面定位功能 和 初始化页面定位按钮和暴露定位方法
             * @params cmpMap 地图实例
             * @params api 地图api
             * @params options 定位配置项
             * @params options.showInMap 是否显示定位按钮在地图上
             * @resultFn mapClass.getCurrentPosition 获取定位方法
             * @mapClass.goSearch: params success 定位成功回调
             * @mapClass.goSearch: params error 定位失败回调
             */
            function createGeolocation(success, error) {
                if ($opts.noGeolocate) {return;}
                return geolocation.getCurrentPosition(function (info) {
                    var status = this.getStatus() == BMAP_STATUS_SUCCESS;
                    setTimeout(function () {
                        if (status) {
                            var data = {
                                id: getId(info.point),
                                address: '',
                                cityname: info.address.city,
                                adname: info.address.district,
                                pname: info.address.province,
                                street: info.address.street,
                                position: info.point,
                                country: info.address.country || ''
                            };
                            lbs.$center.user = info.point;
                            createGeocoder(info.point, function (res) {
                                res = checkType.object(res);
                                checkType.function(success)(objectAssign(res, data));
                            });
                        } else {
                            checkType.function(error)(info);
                        }
                    }, 0);
                });
            };

            /**
             * @function createGeocoder
             * @description 开放页面的经纬度转地址 和 地址转经纬度功能
             * @params cmpMap 地图实例
             * @params api 地图api
             */
            function createGeocoder(lnglat, callback) {
                var llat = lanLatPoint(lnglat);
                if (!llat) {checkType.function(callback)();} else {
                    var k = 'location=' + lnglat.lat + ',' + lnglat.lng + '&output=json&pois=1&radius=500&ak=' + key;
                    request.jsonp('http://api.map.baidu.com/geocoder/v2/?' + k, function (result) {
                        if (result&&result.status === 0 && result.result) {
                            var resultItem = result.result;
                            var data = {
                                id: getId(llat),
                                address: resultItem.formatted_address,
                                cityname: resultItem.addressComponent.city,
                                adname: resultItem.addressComponent.district,
                                pname: resultItem.addressComponent.province,
                                street: resultItem.addressComponent.street,
                                position: resultItem.location,
                                country: resultItem.addressComponent.country || ''
                            };
                            var poisItem = null;
                            if (resultItem.pois) {
                                for (var i=0;i<resultItem.pois.length;i++) {
                                    if (Number(resultItem.pois[i].distance) < 2) {
                                        var dis = distance(resultItem.location, {
                                            lng: resultItem.pois[i].point.x,
                                            lat:resultItem.pois[i].point.y
                                        });
                                        if (!poisItem || dis< poisItem.dis) {
                                            poisItem = {
                                                eq: i,
                                                dis:dis
                                            }
                                        }
                                    }
                                }
                            };
                            if (poisItem){
                                poisItem = resultItem.pois[poisItem.eq];
                                data.name = poisItem.name || data.name;
                                // data.address = poisItem.addr || data.address
                            }
                            var pointCache = poiCacheInfos[data.id + ''];
                            poiCacheInfos[data.id + ''] = objectAssign(pointCache || {}, data);
                            checkType.function(callback)(poiCacheInfos[data.id + ''])
                        } else {
                            checkType.function(callback)()
                        }
                    }, function () {
                        checkType.function(callback)();
                    })
                }
            };

            /**
             * @function name createdMapCall
             * @description 打开地图
             * @author ybjuejue
             * @createDate 2018/12/19/019
             * @params x
             */
            function createdMapCall(callback) {
                convertLanLat($opts.center, function (lngLat) {
                    $opts.position = lngLat;
                    cmpMap.enableScrollWheelZoom(true);
                    if (lngLat) {init(lngLat);} else {
                        ipGeolocation.get(function (e) {
                            getSomeCityCenterByLanLat(e.name, function (p) {
                                console.log(p || e.center);
                                init(p|| e.center);
                            }, e.center)
                        })
                    }
                });

                function init(lngLat, name) {
                    cmpMap.centerAndZoom(lngLat, 15);
                    var initCenter = lbs.$map.getCenter();
                    /**标记类操作**/
                    lbs.marker = marker;
                    lbs.$center = {
                        map: initCenter,
                        user: null,
                        city: initCenter
                    };
                    createGeocoder(lngLat, function (e) {
                        lbs.$map.mapCity = {
                            cityname:e?e.cityname:'',
                            citycode:'',
                        };
                        callback();
                    })

                }
            }
            /**
             * @function name distance
             * @description 计算地图两点之间的距离
             * @author ybjuejue
             * @createDate 2018/11/28/028
             * @params p1,p2为经纬度对象
             */
            function distance(p1, p2) {
                return cmpMap.getDistance(lanLatPoint(p1), lanLatPoint(p2))
            };

            /**
             * @function name openMapActionFn
             * @description 构建一个并暴露原始地图的一些操作方式
             * @params cmpMap 地图实例
             * @params api 地图api
             */
            function openMapActionFn() {
                return {
                    city: null,
                    mapCity: null,
                    userCity: null,
                    setFitView: function (e) {
                        // return cmpMap.setFitView(e);
                    },
                    setCenter: function () {
                        var p = lanLatPoint.apply(null, arguments);
                        if (p) {
                            cmpMap.setCenter(p);
                            this.getCenter();
                        }
                    },
                    setZoomAndCenter: function () {
                        cmpMap.centerAndZoom(arguments[1], arguments[0]);
                    },
                    getCenter: function () {
                        var center = cmpMap.getCenter();
                        lbs.$center.map = center;
                        return center;
                    },
                    getZoom: function () {
                        return cmpMap.getZoom();
                    },
                    setZoom: function () {
                        var zoom = Number(arguments[0]);
                        if (zoom) {
                            cmpMap.setZoom(zoom);
                        }
                    },
                    clearInfoWindow: function () {
                        cmpMap.clearInfoWindow();
                    },
                    // 创建一个地图弹框
                    createInfoWindow: function (o, position) {
                        o = checkType.object(o);
                        var content = o.content;
                        var opts = {};
                        if (o.offset) {
                            opts.offset = o.offset;
                        }
                        var a = new api.InfoWindow({
                            content: content,
                            opts: opts
                        });
                        if (a && lanLatPoint(position)) {
                            cmpMap.openInfoWindow(a, lanLatPoint(position));
                        }
                        return a;
                    },
                    /* clearMap: function () {
                         cmpMap.clearMap();
                     },*/
                    getCity: function (callback) {
                        var map = this;
                        createGeocoder(cmpMap.getCenter(), function (e) {
                            var clt = cityCenterLanLats['city' + e.cityname];
                            clt = lanLatPoint(clt);
                            map.mapCity = {
                                cityname: e.cityname,
                                citycode: null
                            };
                            if (!clt) {
                                getSomeCityCenterByLanLat(e.cityname, function (lanLat) {
                                    if (lanLat) {
                                        cityCenterLanLats['city' + e.cityname] = lanLat;
                                        lbs.$center.city = lanLat;
                                    }
                                    checkType.function(callback).call(null, {
                                        cityname: e.cityname,
                                        citycode: null
                                    });
                                })
                            } else {
                                lbs.$center.city = clt;
                                checkType.function(callback).call(null, {
                                    cityname: e.cityname,
                                    citycode: null
                                });
                            }
                        });
                    },
                    setCity: function (citycode, callback) {
                        var map = this;
                        if (citycode) {
                            var nowCityCode = map.mapCity && map.mapCity.citycode ? map.mapCity.citycode : '';
                            if ((citycode != nowCityCode)) {
                                cmpMap.setCity(citycode, function () {
                                    getCityFn(callback);
                                });
                            } else {
                                checkType.function(callback)(map.mapCity)
                            }

                        } else {
                            getCityFn(callback);
                        }

                        function getCityFn(callback) {
                            map.getCity(function (e) {
                                checkType.function(callback).call(null, e);
                            });
                        }
                    }
                };
            }
            /**
             * @function name createPlaceSearch
             * @description 开启搜索功能 并暴露私有搜索接口
             * @params cmpMap 地图实例
             * @params api 地图api
             * @params autoOptions 与高德搜索配置一致
             * @resultFn mapClass.getSearchResultBykey
             * @mapClass.getSearchResultBykey: params searchValue 搜索的内容
             * @mapClass.getSearchResultBykey: params opt 指定搜索参照城市 默认当前城市
             */
            function createPlaceSearch () {
                if (!cmpMap || !api) {
                    console.error('need both map-object and map-api!');
                    return;
                }

                lbs.getPositionDetail = function (id, callBack, error) {
                    if (poiCacheInfos[id+'']) {
                        checkType.function(callBack)(poiCacheInfos[id+''] || {});
                    } else {
                        createGeocoder(id, callBack);
                    }
                };
                if ($opts.autoSearch) {
                    $opts.autoSearchCallback && $opts.autoSearchCallback();
                    lbs.getSearchResultBykey = function (searchValue, opt) {
                        var city = lbs.$map.userCity ? lbs.$map.userCity.cityname : lbs.$map.city ? lbs.$map.city.cityname : lbs.$map.mapCity?lbs.$map.mapCity.cityname : '';
                        // placeSearch.setCityLimit(Boolean(city));
                        var pageIndex = opt.pageIndex > 1? opt.pageIndex : 1;
                        var pageSize = (opt.pageSize || 10);
                        var url = '';
                        var query = '?scope=2&query='+
                            searchValue+'&page_num='+(pageIndex-1)+'&page_size='+pageSize+'&&region='+city+'&output=json&ak='+ $opts.key;
                        if (!$opts.country) {
                            url = 'http://api.map.baidu.com/place/v2/search'
                        } else {
                            url = 'http://api.map.baidu.com/place_abroad/v1/search'
                        }
                        request.jsonp(url+query, function (data) {
                            // console.log(data)
                            if (data.status === 0) {
                                dealSearchData('complete', data, opt, function (res) {
                                    opt.success && opt.success(res);
                                }, searchValue);

                            } else {
                                opt.error && opt.error();
                            }
                        }, function () {
                            opt.error && opt.error();
                        });
                        function dealSearchData(state, info, opt, callBack, value) {
                            var res = {
                                page: {
                                    count: 0,
                                    pageIndex: pageIndex,
                                    pageSize: pageSize,
                                },
                                info: "OK",
                                data: []
                            };
                            if (value) {
                                res.page.value = value;
                            }
                            if (state === 'complete' && info.results) {
                                res = {
                                    page: {
                                        count: info.total,
                                        pageIndex: pageIndex,
                                        pageSize: pageSize,
                                        value:value
                                    },
                                    info: "OK",
                                    data: info.results || []
                                };
                            }
                            var distanceType = lbs.$center.user ? 'user' : 'city';
                            var loadings = 0;
                            var cityCodes = [];
                            if (res.data.length) {
                                if (lbs.$center.user) {
                                    checkType.function(callBack)(dealRes(res));
                                    return;
                                }
                                for (var j =0; j<res.data.length;j++) {
                                    if (cityCodes.indexOf(res.data[j].city) < 0 && res.data[j].city) {
                                        cityCodes.push(res.data[j].city);
                                    }
                                }
                                if(cityCodes.length) {
                                    for (var k=0; k<cityCodes.length;k++) {
                                        (function (i) {
                                            getSomeCityCenterByLanLat(cityCodes[i], function () {
                                                loadings+=1;
                                                if (loadings === cityCodes.length) {
                                                    checkType.function(callBack)(dealRes(res));
                                                }
                                            });
                                        })(k);
                                    }
                                } else {
                                    checkType.function(callBack)(dealRes(res));
                                }
                            }
                            else {
                                checkType.function(callBack)(res);
                            }
                            function dealRes(res) {
                                for (var n =0; n<res.data.length;n++) {
                                    res.data[n].distance = undefined;
                                    res.data[n].distanceType = distanceType;
                                    res.data[n].pname = res.data[n].province;
                                    res.data[n].cityname =res.data[n].city;
                                    res.data[n].adname = res.data[n].area;
                                    res.data[n].street = res.data[n].street ||"";
                                    res.data[n].country =res.data[n].country||"";
                                    res.data[n].position = res.data[n].location;
                                    res.data[n].name = res.data[n].name || '';
                                    res.data[n].id = getId(res.data[n].position);
                                    poiCacheInfos[res.data[n].id + ''] = objectAssign((poiCacheInfos[res.data[n].id + ''] || {}),res.data[n]);
                                    res.data[n] = Object.assign({},poiCacheInfos[res.data[n].id + '']);
                                    var clt = cityCenterLanLats['city'+res.data[n].city];
                                    clt = lanLatPoint(clt);
                                    clt = lbs.$center.user || clt;
                                    if (!clt) {
                                        clt = lbs.$center.city;
                                        res.data[n].distanceType = "map";
                                    }
                                    if (res.data[n].location && clt) {
                                        res.data[n].distance = distance(res.data[n].location, clt)
                                    }
                                }
                                return res;
                            }
                        }
                    }
                }

            };
            /**
             * @function name getSomeCityCenterByLanLat
             * @description 当前某个城市中心所在经纬度
             * @params cityCode 城市代码
             * @params callback 获取完成的回调
             */
            function getSomeCityCenterByLanLat(cityCode, callback, center) {
                var clt = cityCenterLanLats['city' + cityCode];
                clt = lanLatPoint(clt);
                if (!clt) {
                    var warp = document.createElement("div");
                    var tempMap = new api.Map(warp);
                    tempMap.centerAndZoom(center||cmpMap.getCenter(), 15);
                    tempMap.setCurrentCity(cityCode);
                    cityCenterLanLats['city' + cityCode] = tempMap.getCenter();
                    checkType.function(callback)(tempMap.getCenter());
                    warp.style.display = "none";
                    document.body.appendChild(warp);
                    document.body.removeChild(warp);
                } else {
                    checkType.function(callback)();
                }
            };
            /**构建地图经纬度对象**/
            function lanLatPoint(lng, lat) {
                var ln = lng, la = lat;
                if (arguments.length === 1) {
                    if (ln instanceof api.Point) {
                        return ln
                    } else if (Object.prototype.toString.call(ln) === '[object Object]') {
                        ln = lng.lng;
                        la = lng.lat || lat;
                    } else if (Object.prototype.toString.call(ln) === '[object Array]') {
                        ln = lng[0];
                        la = lng[1] || lat;
                    }
                }
                if (typeof ln === 'number' && typeof la === 'number') {
                    return new api.Point(ln, la)
                } else {
                    return undefined
                }
            }
            // 获取像素和地图位置的转换值
            function getPixel(x, y) {
                return new api.Pixel(x, y);
            };

            // 坐标系经纬度转换 callback 为异步回调
            function convertLanLat(lanlat, callback, type) {
                var ln, lat;
                callback = checkType.function(callback);
                type = getLngLatType(type) || $opts.lngLatType;
                if (lanlat instanceof api.Point) {
                    ln = lanlat;
                } else if (Object.prototype.toString.call(lanlat) === '[object Object]') {
                    ln = lanlat.lng;
                    lat = lanlat.lat;
                } else if (Object.prototype.toString.call(lanlat) === '[object Array]') {
                    ln = lanlat[0];
                    lat = lanlat[1];
                }
                if (typeof ln === 'number' && typeof lat === 'number' && type) {
                    var convar = converLnglat({
                        from: type,
                        to: 'bd',

                    })
                    callback(lanLatPoint(ln, lat));

                    // convertor.translate([new api.Point(ln, lat)], type, 5, function (data) {
                    //     var status = data.status;
                    //     var result = data.points;
                    //     if (status === 0 && result && result[0]) {
                    //         callback(result[0]);
                    //     } else {
                    //         callback(lanLatPoint(ln, lat));
                    //     }
                    // });
                } else {
                    callback(lanLatPoint(ln, lat));
                }
            };
            /**
             * @class name marker
             * @description 标记类操作
             * @property create 创建一个标记
             * @create params autoMove 是否将地图移到标记点
             * @create params opt 配置项与高德api一致
             * @property clear 清楚所有标记
             * @clear params marker.id 指定的某个标记对象
             * @property remove 清楚某个标记
             */
            function marker(id, opt, data, autoMove) {
                var markThis = this;
                if (this instanceof marker && opt) {
                    var extData = data || opt.extData || undefined;
                    id = id || 'user_'+new Date().getTime();
                    id = ''+id;
                    var mark = null;
                    if (opt.icon || $opts.markerOption.icon) {
                        opt.icon = opt.icon || $opts.markerOption.icon;
                    }
                    var optOffset = checkType.object($opts.markerOption.offset);
                    var offset = undefined;
                    if (typeof optOffset.x === 'number' && typeof optOffset.y === 'number') {
                        // offset = new api.Pixel(optOffset.x, optOffset.y);
                    }
                    if (opt.offset || offset) {
                        opt.offset = opt.offset || offset
                    }
                    opt.map = cmpMap;
                    opt.position = lanLatPoint(opt.position);
                    if (!$opts.multiMarkers) {
                        for (var key in lbs.$markers) {
                            lbs.$markers[key].remove()
                        }
                    }
                    if (opt.position) {
                        id = getId(opt.position);
                        var myIcon = new api.Icon(opt.icon, new api.Size(opt.offset.x, opt.offset.y), {
                            // 指定定位位置。
                            // imageUrl: opt.icon,
                            // anchor: new api.Size(10, 25),
                            // 设置图片偏移。
                            // 当您需要从一幅较大的图片中截取某部分作为标注图标时，您
                            // 需要指定大图的偏移位置，此做法与css sprites技术类似。
                            imageSize:new api.Size(opt.offset.x, opt.offset.y),
                            imageOffset: new api.Size(0, 0)   // 设置图片偏移
                        });
                        // 创建标注对象并添加到地图
                        mark = new api.Marker(opt.position, {icon: myIcon, offset:new api.Size(0, -10)});
                        cmpMap.addOverlay(mark);

                        if (lbs.$markers[id] instanceof marker) {
                            lbs.$markers[id].remove();
                        }
                        lbs.$markers[id] = markThis;
                        mark.addEventListener('click', function () {
                            isMarkClick = true;
                            checkType.function(lbs.markerOnClick).call(markThis, {
                                id: id,
                                data: extData,
                                distance: distance(mark.getPosition(), lbs.$center.user || lbs.$center.city),
                                distanceType: lbs.$center.user ? 'user' : 'map',
                                position: mark.getPosition()
                            });
                        });
                        if (autoMove) {
                            lbs.$map.setCenter(opt.position);
                        }
                        this.setInfo = function () {
                            if (arguments.length) {
                                extData = arguments[0];
                            }
                        };
                        this.getInfo = function () {
                            return {
                                id: this.id,
                                data: extData,
                                distance: distance(mark.getPosition(), lbs.$center.user || lbs.$center.city),
                                distanceType: lbs.$center.user ? 'user' : 'map',
                                position: mark.getPosition()
                            }
                        };
                        this.getDetail = function (callback, status) {
                            createGeocoder(
                                mark.getPosition(), function (e) {
                                    callback(e);
                                }
                            );
                            // lbs.getPoiDetail(this.id, mark.getPosition(), callback, status)
                        };
                        checkType.function($opts.markerOption.watch)(lbs.$markers);
                    }
                    this.id = id;
                    this.remove = function () {
                        if (mark instanceof api.Marker) {
                            cmpMap.removeOverlay(mark);
                        }
                        delete this.id;
                        delete this.getInfo;
                        delete this.remove;
                        delete this.getDetail;
                        if (id in lbs.$markers) {
                            delete lbs.$markers[id];
                            checkType.function($opts.markerOption.watch)(lbs.$markers);
                        }
                    };
                }
            }
            marker.prototype.clear = function () {
                if (!arguments.length || arguments[0] === true) {
                    for (var key in lbs.$markers) {
                        lbs.$markers[key].remove()
                    }
                } else {
                    var id = arguments[0] || '';
                    lbs.$markers[''+id].remove();
                }
            };
        }
        function lbsMap(dom, options) {
            if (this instanceof lbsMap) {
                var _this = this;
                var elDom = typeof dom === 'string' ? document.querySelector(dom) : dom;
                if (elDom) {
                    _this.destroy = function () {
                        elDom.innerHTML = '';
                        for (var i in _this) {
                            delete _this[i];
                        }
                        if (this.__proto__) {
                            this.__proto__ = null;
                        }
                    };
                    if (window.BMap) {
                        buildMapInit(elDom, options, _this);
                    } else {
                        request.script('https://api.map.baidu.com/getscript?v=3.0&services=&t=20181212102423&ak='+key,function () {
                            buildMapInit(elDom, options, _this);
                        }, handle.error)
                    }

                } else {
                    handle.error();
                    console.error('need a mounted element!')
                }
            } else {
                return new lbsMap(dom, options);
            }
        }
        lbsMap.prototype.ready = function (fn) {
            this.readyCallBack = checkType.function(fn);
        };
        var lbs = new lbsMap(dom, option);
        lbs.ready(option.success);
        return lbs;
    }
    // 标注和查看的页面的uI
    function lbsMapUi(opt, uiOpt) {
        var handle = new callbackIntercept(opt.success, opt.error);
        function geti18nText(callback) {
            if(typeof CMP_LBSMAPUI_I18N_LOADED  == "undefined" && _.i18n) {
                _.i18n.load(cmpBASEPATH+'/i18n/', 'cmp-lbsMapUi',function(){
                    CMP_LBSMAPUI_I18N_LOADED = true;
                    callback();
                },cmpBuildversion);
            } else {
                callback();
            }
        };

        /**
         * @function buildI18n
         * @description 处理国际化
         * @author ybjuejue
         * @createDate 2018/12/13/013
         * @params x
         */
        var i18n = _.i18n || buildI18n;
        function buildI18n(key) {
            var fI18nData = {};
            fI18nData["cmp.lbsMapUi.back"] = "返回";
            fI18nData["cmp.lbsMapUi.sure"] = "确定";
            fI18nData["cmp.lbsMapUi.save"] = "保存";
            fI18nData["cmp.lbsMapUi.cancel"] = "取消";
            fI18nData["cmp.lbsMapUi.search"] = "搜索";
            fI18nData["cmp.lbsMapUi.searchResult"] = "搜索结果，共";
            fI18nData["cmp.lbsMapUi.searchCount"] = "条";
            fI18nData["cmp.lbsMapUi.searchPlace"] = "请输入关键字";
            fI18nData["cmp.lbsMapUi.defaultTitle"] = "地图标注";
            fI18nData["cmp.lbsMapUi.spread"] = "展开";
            fI18nData["cmp.lbsMapUi.fold"] = "收起";
            fI18nData["cmp.lbsMapUi.emptySearch"] = "请输入搜索内容！";
            fI18nData["cmp.lbsMapUi.clickSure"] = "点击了确认操作";
            fI18nData["cmp.lbsMapUi.clickCancel"] = "点击了取消操作";
            fI18nData["cmp.lbsMapUi.nowPosition"] = "当前标注位置";
            fI18nData["cmp.lbsMapUi.viewPosition"] = "当前查看位置";
            fI18nData["cmp.lbsMapUi.removePoint"] = "移除标注";
            fI18nData["cmp.lbsMapUi.markedPosition"] = "已标注位置";
            return fI18nData[key] || '';
        }
        function getDistanceText(obj) {
            var distance = obj.distance;
            if (typeof distance === 'number') {
                if (distance < 1000) {
                    distance = distance.toFixed(1) + '米'
                } else {
                    distance = (distance / 1000).toFixed(2) + '千米'
                }
            } else {
                distance = '未知'
            }
            return '距离' + (obj.distanceType == 'user' ? '当前位置：' : obj.distanceType == 'city' ? '市中心：' : '地图中心：') + distance
        };
        function searchItemTemp(obj, isMarked,isDom) {
            var classname = 'marker-detail-item' + (isMarked ? ' is-marked' : '');
            var innerHtml = '<div class="info-warp">' +
                '<p class="title">' + (obj.name || obj.address) + '</p>' +
                '<p class="distance">' + getDistanceText(obj) + '</p>' +
                '<p class="address">' + (obj.address ||'') + '</p>' +
                '</div>' +
                '<div class="marker-icon-warp"><div class=""><img src="http://cmp/v/img/markered'+(isMarked ? '':'2')+'.png" alt=""></div>' +
                '<p>' + (isMarked ? '已标注' : '点击标注') + '</p>'+
                '</div>';
            var item = null;
            if (isDom) {
                item = document.createElement('div');
                item.className = classname;
                item.innerHTML = innerHtml;
            } else {
                item = '<div class="' + classname + '">' + innerHtml + '</div>'
            }
            return item;
        };
        function domRemove(container, array) {
            array =checkType.array(array);
            for (var i=0;i<array.length;i++) {
                var dom = container.querySelector(array[i]);
                if (dom) {dom.remove();}
            }
        }

        function templateMobile(option) {
            var opt = objectAssign({title:'',hiddenSearch: false,hiddenSure: false}, option||{});
            var framework = document.createElement('div');
            var sureButton = opt.hiddenSure?'':'<span class="nav-text fireSure">'+i18n("cmp.lbsMapUi.save")+'</span>'
            var searchForm = opt.hiddenSearch?'':'<div class="cmp-search-container">' +
                '<form class="input-warp" action="#" onsubmit="return false">' +
                '<input type="search" class="input searchInput"/>' +
                '<div class="placeholder-warp">' +
                '<span class="see-icon-search"></span>'+ i18n("cmp.lbsMapUi.search")+
                '</div>' +
                '<span class="see-icon-close-round-fill clear clearInput"></span>' +
                '</form>' +
                '</div>';
            framework.className = 'cmp_map_framework cmp_map_framework_mobile';
            framework.innerHTML = '<header class="cmp-map-header cmp-bar cmp-bar-nav cmp-flex-header">' +
                '<div class="cmp-action-back cmp-header-left">' +
                '<span class="cmp-icon see-icon-v5-common-arrow-back fireCancel"></span>' +
                '<span class="nav-text fireCancel">'+i18n("cmp.lbsMapUi.back")+'</span>' +
                '</div>' +
                '<div class="cmp-title">'+(i18n(opt.i18n)||'map')+'</div>' +
                '<div class="cmp-header-right nav-text">' +
                sureButton+
                '</div>' +
                '</header>' +
                searchForm+
                '<div class="map-result-warp search-result-parent">' +
                '<div class="cmp-map-container"></div>' +
                '</div>';
            this.framework = framework;
            this.searchResult = function (info, cstr) {
                cstr = checkType.string(cstr);
                var arr = info.data || [];
                var children = checkType.array(arr);
                var classname = 'cmp-result-container' + (children.length ? ' init' : ' no-data');
                var searchResult = document.createElement('div');
                searchResult.className = classname;
                searchResult.innerHTML = '<div class="bottom-title">' +
                    '<div class="pullup-pulldown"><img class="see-icon-up-open click-spread" src="http://cmp/v/img/mapup.png"/></div>' +
                    '<div class="search-bottom-title">'+i18n("cmp.lbsMapUi.searchResult")+'<span>' + (info.page.count + '') + '</span>'+i18n("cmp.lbsMapUi.searchCount")+'</div>' +
                    '</div>' +
                    '<div class="result-container">' + cstr + '</div>';
                return searchResult
            }
            this.infoWindow = function (status) {
                var infoWindow = document.createElement('div');
                infoWindow.className = 'cmp-marker-container';
                infoWindow.innerHTML =  '<div class="marker-detail-title bottom-title">' +
                    (status ? i18n("cmp.lbsMapUi.viewPosition") : i18n("cmp.lbsMapUi.nowPosition")) +
                    '</div>';
                return infoWindow;
            }
            this.localPosition = function (status) {
                var controls = document.createElement('div');
                var hiddenLocal = status?'':'<div class="local-item item"><img src="http://cmp/v/img/maplocation.png" alt=""></div>';
                controls.className = 'controls-warp';
                controls.innerHTML = hiddenLocal +
                    '<div class="add-minus-item">' +
                    '<div class="add-item item "><img src="http://cmp/v/img/mapadd.png" alt=""></div>' +
                    '<div class="minus-item item"><img src="http://cmp/v/img/mapminus.png" alt=""></div>' +
                    '</div>'
                return controls
            }

        }
        function initPageUi(option, mapUi, uiOpt) {
            if (_.dialog) {
                _.dialog.loading({status:'global'});
            }
            option = checkType.object(option);
            var _this = this;
            _this.mapUi = mapUi;
            geti18nText(function () {
                _this.$opt = uiOpt ||{};
                _this.$opt.type = 'mobile';
                _this.$data = _this.$opt.data;
                var uiTemplateFn = templateMobile;
                _this.$uiTemplate = new uiTemplateFn(_this.$opt);
                _this.$container = _this.$uiTemplate.framework;
                _this.style = createStyle();
                document.body.appendChild(_this.$container);
                document.body.appendChild(_this.style);
                _this.map = lbsMapBase(_this.$container.querySelector('.cmp-map-container'), {
                    autoSearch: true,
                    multiMarkers: true,
                    noGeolocate: false,
                    lngLatType: 'gps',
                    markerOption: {
                        icon: '<span class="marker see-icon-map-mark"></span>',
                        offset: {x: -13, y: -23},
                        watch: function (e) {
                            checkType.function(_this.markerChange).call(_this, e);
                        }
                    }
                });
                _this.mapUiOwnProperty();
                _this.bindPageEvent();
                _this.pageUiOwnProperty();
            })
        }
        initPageUi.prototype.bindListen = function (selector, events) {
            if (this.$container) {
                var selectorNode = this.$container.querySelectorAll(selector);
                events = checkType.object(events);
                if (selectorNode.length) {
                    for (var i=0;i<selectorNode.length;i++) {
                        for (var type in events) {
                            selectorNode[i].addEventListener(type, checkType.function(events[type]), false);
                        }
                    }

                }
                return selectorNode?selectorNode[0]:undefined;
            }
        };
        initPageUi.prototype.bindPageEvent = function () {
            var _this = this;
            _this.bindListen('.cmp_map_framework', {
                click: function (e) {
                }
            })
            _this.bindListen('.searchInput', {
                blur: function (e) {
                    checkValue.call(this, e);
                },
                keyup: function (e) {
                    if (e.keyCode == 13) {
                        _this.onsearch(e, this, true);
                        if (this.value) {
                            this.blur();
                        }
                    }
                }
            });
            _this.bindListen('.clearInput', {
                click: function () {
                    _this.bindListen('.searchInput').value = '';
                    checkValue.call(_this.bindListen('.searchInput'));
                }
            })
            _this.bindListen('.fireSure', {
                click: function () {
                    checkType.function(_this.mapUi.onsure).call(_this.mapUi, _this.map.$markers);
                }
            });
            _this.bindListen('.fireCancel', {
                click: function () {
                    checkType.function(_this.mapUi.oncancel).call(_this.mapUi, _this.map.$markers);
                }
            });
            _this.bindListen('.clear-marks', {
                click: function (e) {
                    clearMarkers(_this.map, true);
                }
            });
            _this.bindListen('.search-button', {
                click: function (e) {
                    _this.onsearch(e, _this.bindListen('.searchInput'), true);
                    if (_this.bindListen('.searchInput').value) {
                        _this.bindListen('.searchInput').blur();
                    }
                }
            });
            function checkValue() {
                var className = this.className
                if (this.value) {
                    if (className.indexOf(' has-value') < 0) {
                        this.className += ' has-value';
                    }
                } else {
                    if (className.indexOf(' has-value') >= 0) {
                        this.className = this.className.replace(' has-value', '');
                    }
                }
            }
        };
        initPageUi.prototype.pageUiOwnProperty = function () {
            var map = this.map;
            var _this = this;
            var firstGeo = true;
            _this.$markersLength = 0;
            _this.map.ready(function () {
                if (_.dialog) {
                    _.dialog.loading(false);
                }
                if (_this.$data.lbsPoiId || (_this.$data.lbsLatitude && _this.$data.lbsLongitude)) {
                    buildMarkData(_this.map,{
                        id:_this.$data.lbsPoiId,
                        position:[_this.$data.lbsLongitude, _this.$data.lbsLatitude]
                    }, 1);
                };
                if (_this.$opt.readyCall) {
                    handle.success();
                }
                var localPosition = _this.$uiTemplate.localPosition(_this.$opt.noLocal);
                _this.bindListen('.search-result-parent').appendChild(localPosition);
                _this.bindListen('.local-item', {
                    click: function () {
                        _this.getCurrentPosition(this);
                    }
                });
                _this.bindListen('.add-item', {
                    click: function () {
                        map.$map.setZoom(map.$map.getZoom() + 1);
                    }
                });
                _this.bindListen('.minus-item', {
                    click: function () {
                        map.$map.setZoom(map.$map.getZoom() - 1);
                    }
                });
                if (!_this.$opt.noLocal){
                    _this.getCurrentPosition = function () {
                        if (_this.bindListen('.local-item')) {
                            _this.bindListen('.local-item').classList.add('local-loading');
                        }
                        _.h5lbs.getCurrentPosition({
                            success:function (e) {
                                if (_this.bindListen('.local-item')) {
                                    _this.bindListen('.local-item').classList.remove('local-loading');
                                }
                                if (!_this.$markersLength) {
                                    map.convertLanLat({
                                        lng: e.coordinate.longitude,
                                        lat: e.coordinate.latitude
                                    }, function (ll) {
                                        buildMarkData(map, {
                                            position: ll
                                        }, 1,_this);
                                    }, 'gd');

                                }
                                if (firstGeo && _this.$markersLength) {
                                    firstGeo = false;
                                    return false;
                                }
                                firstGeo = false;
                            },
                            error: function () {
                                console.log(22)
                                if (_this.bindListen('.local-item')) {
                                    _this.bindListen('.local-item').classList.remove('local-loading');
                                }
                            }
                        });
                    };
                    _this.getCurrentPosition();
                }

                map.onLocalMarkerClick = function (e) {
                    clearMarkers(map);
                    domRemove(_this.$container, ['.cmp-result-container', '.cmp-marker-container']);
                    e.position = e.target.getPosition() || e.lnglat;
                    buildMarkData(map, e, 1,_this)
                };
                map.onclick = function (e) {
                    domRemove(_this.$container, ['.cmp-result-container', '.cmp-marker-container']);
                    e.position = e.position || e.lnglat;
                    if (!_this.$opt.noMapClick) {
                        if (e.id) {
                            _this.map.getPoiDetail(e.id, e.position, function (r) {
                                createInfoAlert(r);
                            })
                        }
                    }
                };
                map.markerOnClick = function (e) {
                    domRemove(_this.$container, ['.cmp-result-container', '.cmp-marker-container']);

                    if (e.data.status) {
                        this.getDetail(function (r) {
                            createInfoAlert(r);
                        })
                    } else {
                        var s = buildMarkData(map, e, 1,_this);
                    }
                }
            });
            function createInfoAlert(r) {
                var newMarker = _this.map.$markers[r.id + ''];
                _this.markerDetailUi(r, !newMarker);
            }
            _this.onsearch = function (e, dom, s) {
                var _this = this;
                if (s) {
                    if (!dom.value) {
                        _.notification.close();
                        _.notification.alert(i18n("cmp.lbsMapUi.emptySearch"));
                        dom.blur();
                        return
                    }
                    clearMarkers(_this.map);
                    domRemove(_this.$container, ['.cmp-result-container', '.cmp-marker-container']);
                    _this.goSearch(dom.value, {}, function (m) {
                        if (m.data.length === 1) {
                            buildMarkData(_this.map, m.data[0], 1, _this);
                            _this.map.$map.getCity();
                        } else {
                            _this.searchResultUi(m);
                        }
                    });
                }
            };
            _this.markerItemUi = function (obj, status) {
                var _this = this;
                var markers = this.map && this.map.$markers ? this.map.$markers : {};
                obj = checkType.object(obj);
                var classname = ['marker-detail-item'];
                var isMarked = markers[obj.id] && markers[obj.id].getInfo().data.status;
                if (isMarked) {
                    classname.push('is-marked');
                } else if (!status) {
                    buildMarkData(_this.map, obj, 0, _this);
                }
                var markerItem = searchItemTemp(obj, isMarked, true);
                markerItem.querySelector('.marker-icon-warp').addEventListener('click', function () {
                    if (_this.$opt.noSetMark) {
                        return;
                    }
                    buildMarkData(_this.map, obj, 1, _this);
                    _this.map.$map.getCity();
                    domRemove(_this.$container, ['.cmp-result-container', '.cmp-marker-container']);
                }, false);
                return markerItem;
            };
            _this.searchResultUi = function (info) {
                var arr = info.data || [];
                clearMarkers(_this.map);
                domRemove(_this.$container, ['.cmp-result-container', '.cmp-marker-container']);
                var children = checkType.array(arr);
                var searchResult = _this.$uiTemplate.searchResult(info);
                _this.bindListen('.search-result-parent').appendChild(searchResult);
                _this.bindListen('.click-spread', {
                    click: function () {
                        var cl = searchResult.className;
                        var isPc = _this.$opt.type == 'pc';
                        if (cl.indexOf('spread') >= 0) {
                            if (isPc){this.innerHTML = i18n("cmp.lbsMapUi.spread")} else {
                                this.className = 'click-spread';
                                this.src='http://cmp/v/img/mapup.png'
                            };
                            searchResult.className = cl.replace('spread', '')
                        } else {
                            searchResult.className += (' spread');
                            if (isPc){this.innerHTML = i18n("cmp.lbsMapUi.fold")}else {
                                this.className = 'click-spread';
                                this.src='http://cmp/v/img/mapdown.png'
                            };
                        }
                    }
                });
                _this.bindListen(".result-container", {
                    scroll: function (e) {
                        _this.loadMore(e, this)
                    }
                });
                for (var i = 0; i < children.length; i++) {
                    _this.bindListen(".result-container").appendChild(_this.markerItemUi(children[i]));
                }
                _this.map.$map.setFitView();
            };
            _this.markerDetailUi = function (obj, status) {
                domRemove(_this.$container, ['.cmp-result-container', '.cmp-marker-container'])
                var markerDetail = _this.$uiTemplate.infoWindow(status);
                _this.bindListen('.search-result-parent').appendChild(markerDetail);
                markerDetail.appendChild(_this.markerItemUi(obj, status));
            };

        };
        initPageUi.prototype.mapUiOwnProperty = function () {
            var _this = this;
            /**
             * @function name destroy
             * @description 添加页面销毁函数
             * @author ybjuejue
             * @createDate 2018/12/7/007
             */
            _this.mapUi.destroy = function () {
                if (_this.map) {
                    _this.map.destroy();
                }
                _this.$container.parentElement.removeChild(_this.$container);
                _this.style.parentElement.removeChild(_this.style);
                _this.$container = null;
                _this.style = null;
                for (var i in _this.mapUi) {
                    delete _this.mapUi[i];
                }
                if (_this.mapUi.__proto__) {
                    _this.mapUi.__proto__ = null;
                }
            };
            _this.mapUi.show = function () {
                _this.$container.style.display = 'block';
            };
            _this.mapUi.hidden = function () {
                _this.$container.style.display = 'none';
            };
        };
        initPageUi.prototype.markerChange = function (markers) {
            var length = 0;
            var state = 'none';
            markers = checkType.object(markers);
            for (var i in markers) {
                if (markers[i] && markers[i].getInfo && markers[i].getInfo().data.status) {
                    length++;
                }
            }
            if (length) {
                state = 'inline-block'
            }
            this.$markersLength = length;
            var clearMarksButton = this.bindListen('.clear-marks');
            if (clearMarksButton) {
                clearMarksButton.style.display = state;
            }

        };
        initPageUi.prototype.goSearch = function (value, pt, callback) {

            var _this = this;
            if (_this.loading) {
                return
            }
            _this.loading = true;
            pt = checkType.object(pt);

            _this.map.getSearchResultBykey(value, {
                pageSize: 10,
                pageIndex: pt.pageIndex || 1,
                success: function (m) {
                    delete _this.loading;
                    _this.searchPage = m.page;
                    checkType.function(callback)(m);
                },
                error: function () {
                    delete _this.loading;
                }
            })
        };
        initPageUi.prototype.loadMore = function (e, dom) {
            var _this = this;
            var sh = dom.scrollHeight;
            var dh = dom.offsetHeight;
            var st = dom.scrollTop;
            var isBottom = (dh + st + 100) >= sh;
            if (isBottom && _this.searchPage.pageIndex * _this.searchPage.pageSize < _this.searchPage.count) {
                _this.goSearch(_this.searchPage.value, {
                    pageIndex: _this.searchPage.pageIndex + 1
                }, function (e) {
                    if (dom) {
                        for (var i = 0; i < e.data.length; i++) {
                            dom.appendChild(_this.markerItemUi(e.data[i]));
                        }
                    }
                    delete _this.loading
                })
            }
        };
        function createStyle() {
            var style = document.createElement('style');
            return style;
        };
        function clearMarkers(map, all) {
            if (map.$markers) {
                var $markers = map.$markers;
                for (var k in $markers) {
                    if (!$markers[k].getInfo().data.status || all) {
                        $markers[k].remove();
                    }
                }
            }
        };
        function buildMarkData(map, e, status, ui) {
            if (!map.marker) {return}
            var opt = {
                position: e.position || e.lnglat
            };
            if (status) {
                opt.icon = 'http://cmp/v/img/markered.png'
                opt.offset = {
                    x:25,
                    y:25
                }
            } else {
                opt.icon = 'http://cmp/v/img/map-search-local.png';
                opt.offset = {
                    x:20,
                    y:23
                }
            }
            if (status) {
                clearMarkers(map, status);
            }
            var marker = new map.marker(e.id, opt, {
                status: status,
                info: e
            }, Boolean(status));
            if (status) {
                map.$map.setFitView();
                marker.getDetail(function (r) {});
            }
            return marker
        };
        /**
         * @function cmpMapUi
         * @description lbs地图ui
         * @params option 配置对象
         * @params option.key 来自高德地图的api key
         * @params option.title 设置页面标题
         */
        function cmpMapUi(option, uiOpt) {
            if (lbsMapBase) {
                if (this instanceof cmpMapUi) {
                    new initPageUi(option, this,uiOpt);
                    this.oncancel = function () {
                        var _this = this;
                        option.cancel&&option.cancel();
                        _this.destroy();
                    };
                    this.onsure = function ($markers) {
                        var _this = this;
                        actionBack();
                        function actionBack() {
                            var marker = null;
                            for (var i in ($markers||{})) {
                                if ($markers[i] && $markers[i].getInfo && $markers[i].getInfo().data.status) {
                                    marker = $markers[i];
                                }
                            }
                            if (marker) {
                                marker.getDetail(function (e) {
                                    var needKey = [
                                        'address',
                                        'cityname',
                                        'pname',
                                        'adname',
                                        'street'
                                    ];
                                    var status = true;
                                    for (var i =0;i<needKey.length;i++){
                                        if (!e[needKey[i]]) {
                                            status = false;
                                            break;
                                        }
                                    }
                                    if (!status) {
                                        marker.getDetail(function (s) {
                                            for (var i =0;i<needKey.length;i++){
                                                if (!e[needKey[i]]) {
                                                    e[needKey[i]] = s[needKey[i]];
                                                }
                                            }
                                            handle.success(e);
                                            _this.destroy();
                                        }, !status);
                                    } else {
                                        handle.success(e);
                                        _this.destroy();
                                    }
                                })
                            } else {
                                _this.destroy();
                            }

                        }
                    };
                } else {
                    return new cmpMapUi(option);
                }
            } else {
                handle.error({
                    error: 'this component need lbaMap-class!'
                });
            }
        }
        var lbsUi = new cmpMapUi(opt, uiOpt);
        return lbsUi;
    }
    function converFrom() {
        //定义一些常量
        var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
        var PI = 3.1415926535897932384626;
        var a = 6378245.0;
        var ee = 0.00669342162296594323;

        /**
         * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
         * 即 百度 转 谷歌、高德
         * @param bd_lon
         * @param bd_lat
         * @returns {*[]}
         */
        function bdTogcj(bd_lon, bd_lat) {
            var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
            var x = bd_lon - 0.0065;
            var y = bd_lat - 0.006;
            var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
            var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
            var gg_lng = z * Math.cos(theta);
            var gg_lat = z * Math.sin(theta);
            return [gg_lng, gg_lat]
        }

        /**
         * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
         * 即谷歌、高德 转 百度
         * @param lng
         * @param lat
         * @returns {*[]}
         */
        function gcjTobd(lng, lat) {
            var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
            var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
            var bd_lng = z * Math.cos(theta) + 0.0065;
            var bd_lat = z * Math.sin(theta) + 0.006;
            return [bd_lng, bd_lat]
        }

        /**
         * WGS84转GCj02
         * @param lng
         * @param lat
         * @returns {*[]}
         */
        function wgsTogcj(lng, lat) {
            if (out_of_china(lng, lat)) {
                return [lng, lat]
            }
            else {
                var dlat = transformlat(lng - 105.0, lat - 35.0);
                var dlng = transformlng(lng - 105.0, lat - 35.0);
                var radlat = lat / 180.0 * PI;
                var magic = Math.sin(radlat);
                magic = 1 - ee * magic * magic;
                var sqrtmagic = Math.sqrt(magic);
                dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
                dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
                var mglat = lat + dlat;
                var mglng = lng + dlng;
                return [mglng, mglat]
            }
        }

        /**
         * GCJ02 转换为 WGS84
         * @param lng
         * @param lat
         * @returns {*[]}
         */
        function gcjTowgs(lng, lat) {
            if (out_of_china(lng, lat)) {
                return [lng, lat]
            }
            else {
                var dlat = transformlat(lng - 105.0, lat - 35.0);
                var dlng = transformlng(lng - 105.0, lat - 35.0);
                var radlat = lat / 180.0 * PI;
                var magic = Math.sin(radlat);
                magic = 1 - ee * magic * magic;
                var sqrtmagic = Math.sqrt(magic);
                dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
                dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
                mglat = lat + dlat;
                mglng = lng + dlng;
                return [lng * 2 - mglng, lat * 2 - mglat]
            }
        }


        function bdTowgs(lng, lat) {
            var lnglat = bdTogcj(lng, lat);
            return gcjTowgs(lnglat[0], lnglat[1])
        }
        function wgsTobd(lng, lat) {
            var lnglat = wgsTogcj(lng, lat);
            return gcjTobd(lnglat[0], lnglat[1])
        }

        function transformlat(lng, lat) {
            var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
            ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
            ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
            return ret
        }

        function transformlng(lng, lat) {
            var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
            ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
            ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
            return ret
        }
        /**
         * 判断是否在国内，不在国内则不做偏移
         * @param lng
         * @param lat
         * @returns {boolean}
         */
        function out_of_china(lng, lat) {
            return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
        }
        // 操作函数
        return function(opt) {
            var lnglat = (opt || {}).lnglat;
            if (typeof lnglat.lat ==='number' && typeof lnglat.lng==='number'&&Math.abs(lnglat.lng)<=180&&Math.abs(lnglat.lat)<=90) {
                type = {
                    'bdTogcj':bdTogcj,
                    'gcjTobd':gcjTobd,
                    'wgsTogcj':wgsTogcj,
                    'gcjTowgs':gcjTowgs,
                    'bdTowgs':bdTowgs,
                    'wgsTobd':wgsTobd
                }
                var callName = opt.from +'To'+ opt.to;
                if (!type[callName]) {
                    return [lnglat.lng,lnglat.lat]
                } else {
                    return type[callName](lnglat.lng,lnglat.lat);
                }
            } else {
                return;
            }
        }
    }
})(window.cmp);